﻿
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;

namespace HDJ.Framework.Core
{
    public static class LogManager
    {

        //public static void Init()
        //{
        //    Type t = typeof(Debug);
        //    FieldInfo field = t.GetField("s_Logger", BindingFlags.NonPublic | BindingFlags.Static);
        //    NLoggerHandler handle = new NLoggerHandler();
        //    Logger logger = new Logger(handle);
        //    field.SetValue(null, logger);
        //    Debug.Log("UnityDebugExtends");
        //}

        public static CallBack<LogInfo> OnAddLogInfo;


        private static NLoggerHandler handle = null;

        private static List<LogInfo> infoLogInfos = new List<LogInfo>();
        private static List<LogInfo> warningLogInfos = new List<LogInfo>();
        private static List<LogInfo> errorLogInfos = new List<LogInfo>();

        public static void Init(LogType logType = LogType.Log)
        {

            handle = new NLoggerHandler();

            Debug.unityLogger.filterLogType = logType;

            //在这里做一个Log的监听  
            //转载的原文中是用Application.RegisterLogCallback(HandleLog);但是这个方法在unity5.0版本已经废弃不用了  
            Application.logMessageReceivedThreaded += HandleLog;
        }
        public static void Close()
        {
            if (handle != null)
            {
                handle.Close();
            }
            Application.logMessageReceivedThreaded -= HandleLog;
        }

        private static int indexCounter = 0;
        static void HandleLog(string logString, string stackTrace, LogType logType)
        {
            LogInfo info = new LogInfo(indexCounter, logType, logString, stackTrace);
            indexCounter++;
            switch (logType)
            {
                case LogType.Error:
                case LogType.Assert:
                case LogType.Exception:
                    errorLogInfos.Add(info);
                    break;
                case LogType.Warning:
                    warningLogInfos.Add(info);
                    break;
                case LogType.Log:
                    infoLogInfos.Add(info);
                    break;

            }

            handle.LogFormat(logType, null, "{0}\n{1}", new object[] { logString, stackTrace });

            if (OnAddLogInfo != null)
            {
                OnAddLogInfo(info);
            }
        }

        public static void Clear()
        {
            indexCounter = 0;
            errorLogInfos.Clear();
            warningLogInfos.Clear();
            infoLogInfos.Clear();
        }
        public static int GetLogInfoCount(LogType logType)
        {
            switch (logType)
            {
                case LogType.Error:
                case LogType.Assert:
                case LogType.Exception:
                    return errorLogInfos.Count;

                case LogType.Warning:
                    return warningLogInfos.Count;

                case LogType.Log:
                    return infoLogInfos.Count;

            }
            return 0;
        }
        public static void GetLoginfos(List<LogType> logType, List<LogInfo> infos)
        {
            if (infos == null)
                infos = new List<LogInfo>();
            else
                infos.Clear();

            if (logType.Contains(LogType.Log))
            {
                infos.AddRange(infoLogInfos);
            }
            if (logType.Contains(LogType.Warning))
            {
                infos.AddRange(warningLogInfos);
            }
            if (logType.Contains(LogType.Error) || logType.Contains(LogType.Assert) || logType.Contains(LogType.Exception))
            {
                infos.AddRange(errorLogInfos);
            }

            infos.Sort((LogInfo a, LogInfo b) =>
            {
                if (a.index > b.index)
                    return 1;
                if (a.index < b.index)
                    return -1;
                return 0;
            });
        }

    }
}
